/*
 * LinkedListImpl.cpp
 *
 *  Created on: Apr 25, 2012
 *      Author: REZNIK
 */

#include "LinkedListImpl.h"
#include "ListIterator.h"
#include "NodeImmutable.h"
#include "NodeMuatble.h"

using namespace cs236703_spring2012_hw2;

namespace cs236703_spring2012_hw2{

	LinkedListImpl::LinkedListImpl(): 	version(0), size(0){
		head.AddRef();
		head.SetPrev(&head);
		head.SetNext(&tail);
		tail.AddRef();
		tail.SetPrev(&head);
		tail.SetNext(&tail);
	}
	LinkedListImpl::~LinkedListImpl() {
		Iterator* iter = GetIterator();
		while(iter->HasNext()){
			iter->Next();
			iter->Remove();
		}
		delete iter;
	}

	Iterator* LinkedListImpl::GetIterator() {
		return new ListIterator(this, &head, version);
	}
	// Get the content version. The version is updated on every addition or delete.
	int LinkedListImpl::GetVersion() const { return version; }

	Node* LinkedListImpl::getNewNode(int i, bool immutable){
		Node* newNode = NULL;
		if(immutable){
			newNode = new NodeImmutable(i);
		}else{
			newNode = new NodeMutable(i);
		}
		UpdateVersion();
		newNode->AddRef();
		size++;
		return newNode;
	}

	//updates counters
	void LinkedListImpl::removeNode(Node* node){
		UpdateVersion();
		node->RemoveRef();
		size--;
	}
	// Add a new element at the beginning of the list
	void LinkedListImpl::AddToFront(int i, bool immutable){
		Node* newNode = LinkedListImpl::getNewNode(i, immutable);
		head.GetNext()->SetPrev(newNode);
		newNode->SetNext(head.GetNext());
		newNode->SetPrev(&head);
		head.SetNext(newNode);
	}
	// Add a new element at the end of the list
	void LinkedListImpl::AddToBack(int i, bool immutable){
		Node* newNode = LinkedListImpl::getNewNode(i, immutable);
		tail.GetPrev()->SetNext(newNode);
		newNode->SetPrev(tail.GetPrev());
		newNode->SetNext(&tail);
		tail.SetPrev(newNode);
	}

	void LinkedListImpl::UpdateVersion(){
		version++;
	}

	List* GetNewList(){
		return (new LinkedListImpl() );
	}

};


